package common.util;


import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch._types.FieldValue;
import co.elastic.clients.elasticsearch._types.query_dsl.Query;
import co.elastic.clients.elasticsearch._types.query_dsl.TermsQuery;
import co.elastic.clients.elasticsearch._types.query_dsl.TermsQueryField;
import co.elastic.clients.elasticsearch.core.KnnSearchResponse;
import co.elastic.clients.elasticsearch.core.search.TotalHits;
import co.elastic.clients.elasticsearch.core.search.TotalHitsRelation;
import com.alibaba.fastjson.JSONObject;
import com.yuntsg.ruiijn.databse_search.entity.NcbiPdfToJpg;
import com.yuntsg.ruiijn.databse_search.entity.TextParagraph;
import common.vo.FetchVectorVo;
import common.vo.FetchVectorVoStep;
import common.vo.PubVectorImageRes;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@SuppressWarnings("all")
@Component
public class CentralRequestUtil {

    @Autowired
    private ElasticsearchClient esClient;
    @Value("${central.api.url}")
    private String centralServer;
    @Value("${central.api.appKey}")
    private String centralAppKey;

    public static void main(String[] args) {
        FetchVectorVo fetchVectorVo = new FetchVectorVo();
        fetchVectorVo.setTopK(200);
        fetchVectorVo.setSearchVector(Arrays.asList(0.0, 0.0, 0.0, 0.0, 0.06322405487298965, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.011142760515213013, 0.0, 0.01740081235766411, 0.0219997838139534, 0.0, 0.0, 0.0, 0.04194895550608635, 0.0, 0.0, 0.0, 0.0, 0.10377231985330582, 0.0011168845230713487, 0.0, 0.0, 0.0, 0.04113340750336647, 0.0, 0.026583347469568253, 0.0, 0.0, 0.0, 0.0, 0.0, 0.16192607581615448, 0.0, 0.03433059900999069, 0.01726430281996727, 0.09141410887241364, 0.0, 0.0, 0.0, 0.0, 0.0022620069794356823, 0.062113065272569656, 8.651074022054672E-4, 0.023993775248527527, 0.046762093901634216, 0.05700049176812172, 0.02765694260597229, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.02538345381617546, 0.03223132714629173, 0.0, 0.014757230877876282, 0.0, 0.0, 0.0, 0.0, 0.0, 0.009785141795873642, 0.08119558542966843, 0.034632179886102676, 0.0, 0.0, 0.01125315111130476, 0.0, 0.0, 0.0, 0.0, 0.037524618208408356, 0.14955101907253265, 0.0, 0.06093430519104004, 0.0, 0.036032289266586304, 0.0, 0.08656278252601624, 0.0, 0.0, 0.0, 0.0, 0.0, 0.03393389284610748, 0.0515604093670845, 0.0, 0.0, 0.0, 0.0698334127664566, 0.0, 0.0, 0.0, 0.02586066536605358, 0.0, 0.026796970516443253, 0.020537223666906357, 0.0, 0.0, 0.0, 0.030030548572540283, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1370656043291092, 0.13658523559570312, 0.0, 0.021844489499926567, 0.0, 0.0, 0.0, 0.13481023907661438, 0.06995152682065964, 0.018118472769856453, 0.0, 0.0, 0.09224631637334824, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.014841492287814617, 0.0, 0.05375320464372635, 0.054211605340242386, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.042953651398420334, 0.01776880957186222, 0.0, 0.0, 0.0, 0.04830572009086609, 0.0544927716255188, 0.04803422838449478, 0.009884318336844444, 0.0, 0.0, 0.09201640635728836, 0.0, 0.0, 0.052949950098991394, 0.0, 0.007202662527561188, 0.008805613964796066, 0.0, 0.09909741580486298, 0.02052166499197483, 0.036419592797756195, 0.0, 0.11077260971069336, 0.0, 0.0, 0.10904398560523987, 3.7060954491607845E-4, 0.010730023495852947, 0.0, 0.09487288445234299, 0.0, 0.0, 0.0, 0.04023992642760277, 0.0, 0.051262710243463516, 0.0, 0.029140356928110123, 0.02601144090294838, 0.0, 0.015236997045576572, 0.0, 0.0, 0.0, 0.003989142365753651, 0.0, 0.051399264484643936, 0.0, 0.0, 0.04855414852499962, 0.0, 0.012911323457956314, 0.0, 0.0, 0.0, 0.059460245072841644, 0.0, 0.13574323058128357, 0.021230772137641907, 0.0, 0.0, 0.0, 0.003580594900995493, 0.0, 0.0, 0.03535202145576477, 0.020551228895783424, 0.057575467973947525, 0.05888219550251961, 0.0, 0.0, 0.0, 0.03205503895878792, 0.004876259248703718, 0.0, 0.06236708164215088, 0.0, 0.0, 0.0, 0.0, 0.015194268897175789, 0.0, 3.111333353444934E-4, 0.0, 0.01670040562748909, 0.0, 0.03713921830058098, 0.0, 0.0, 0.0, 0.16364942491054535, 0.02994854748249054, 0.0, 0.10677509754896164, 0.0, 0.004111174959689379, 0.0, 0.0, 0.06164368614554405, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.038300782442092896, 0.0364733524620533, 0.029094507917761803, 0.021096335723996162, 0.05210356414318085, 0.0, 0.0, 0.0, 0.0, 0.04402938112616539, 0.002429060870781541, 0.0, 0.016198430210351944, 0.0, 0.0, 0.0080078961327672, 0.035653989762067795, 0.11858325451612473, 0.0, 0.0, 0.0, 0.06538990139961243, 0.0, 0.1582518368959427, 0.0, 0.0, 0.07049785554409027, 0.1370970904827118, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.10230738669633865, 0.0, 0.0, 0.0, 0.0, 0.0, 0.07340867072343826, 0.0, 0.0, 0.0, 0.03296934813261032, 0.0, 0.0, 2.018038503592834E-4, 0.0, 0.0, 0.02642424963414669, 0.11096016317605972, 0.0, 0.004352387506514788, 0.0, 0.0, 0.0, 0.0, 0.0, 0.07551613450050354, 0.0, 0.12528862059116364, 0.0, 0.1013663113117218, 0.0, 0.007572212256491184, 0.0, 0.04136556759476662, 0.0, 0.03319767862558365, 0.13940462470054626, 0.0, 0.11465740948915482, 0.0, 0.0, 0.005206120200455189, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.043027713894844055, 0.0, 0.0, 0.0, 0.048097431659698486, 0.057735249400138855, 0.1886466145515442, 0.08947127312421799, 0.012610257603228092, 0.23394054174423218, 0.0, 0.0, 0.0, 0.0, 0.03940533474087715, 0.0, 0.046819478273391724, 0.0, 0.08604739606380463, 0.0, 0.0, 0.057291027158498764, 0.0, 0.0, 0.02084522694349289, 0.1986910104751587, 0.0, 0.0, 0.0, 0.016334591433405876, 0.027291396632790565, 0.07900382578372955, 0.0, 0.0, 0.0, 0.0, 0.0, 0.07578622549772263, 0.0, 0.0, 0.0, 0.0, 0.0, 0.06505082547664642, 0.04935474321246147, 0.0, 0.0, 0.0036050446797162294, 0.0, 0.044891562312841415, 0.0, 0.0, 0.0235635656863451, 0.0, 0.09094676375389099, 0.0, 0.0, 0.0, 0.0, 0.08084939420223236, 0.0, 0.0, 0.0, 0.0, 0.043861813843250275, 0.0, 0.0, 0.02977878414094448, 0.0, 0.09791724383831024, 0.23508062958717346, 0.0, 0.0, 0.0, 0.0, 0.20007124543190002, 0.0, 0.0, 0.0, 0.10263033211231232, 0.0, 0.0, 0.034083686769008636, 0.0, 0.0, 0.0, 0.0, 0.025343243032693863, 0.004931480158120394, 0.0, 0.0, 0.0, 0.10754626244306564, 0.0, 0.052572254091501236, 0.0, 0.051983997225761414, 0.007749101612716913, 0.0, 0.0, 0.0, 0.0, 0.0, 0.14233407378196716, 0.0, 0.0, 0.12258235365152359, 0.08130362629890442, 0.0, 0.0, 0.0, 0.0, 0.03012222982943058, 0.0, 0.0, 0.0, 0.07773841917514801, 0.09755421429872513, 0.021785296499729156, 4.4306524796411395E-4, 0.01642633229494095, 0.0, 0.0, 0.0, 0.0, 0.00682933209463954, 0.05013028159737587, 0.002191057661548257, 0.0, 0.0, 0.0, 0.10022273659706116, 0.0, 0.1591680496931076, 0.0, 0.0, 0.10732228308916092, 0.0, 0.0, 0.008508275263011456, 0.013110605999827385, 0.0, 0.0, 0.08594091981649399, 0.0, 0.01022003311663866, 0.0, 0.026027053594589233, 0.0, 0.002503607887774706, 0.0, 0.0, 0.0, 0.010016152635216713, 0.0, 0.04375216364860535, 0.0, 0.02313523180782795, 0.017129383981227875, 0.0, 0.0031875830609351397, 0.0, 0.0011623352766036987, 0.0, 0.008676929399371147, 0.013610557653009892, 0.06156414747238159, 0.019535692408680916, 0.08535042405128479, 0.0, 0.029311155900359154, 0.0, 0.02329823561012745, 0.0));
        fetchVectorVo.setSource(0);
        fetchVectorVo.setPmut("33619876");
        fetchVectorVo.setAppKey("100");

        String post = HttpUtil.post("http://10.1.1.19:8851/" + "centralapi/fetchVector", JSONObject.toJSONString(fetchVectorVo));
        JSONObject r = JSONObject.parseObject(post);
    }

    public FetchVectorVoStep pubSearchImage(Integer topK, List<Double> searchVector, Integer source, String pmut) {
        FetchVectorVo fetchVectorVo = new FetchVectorVo().setTopK(topK).setSource(source).setPmut(pmut).setAppKey(centralAppKey).setSearchVector(searchVector);
        try {
            if (source == 0) {
                String post = HttpUtil.post(centralServer + "centralapi/fetchVector", JSONObject.toJSONString(fetchVectorVo));
                JSONObject r = JSONObject.parseObject(post);
                if (r.get("code").equals(0)) {
                    return new FetchVectorVoStep().setData(JSONObject.parseArray(r.getString("data"), PubVectorImageRes.class)).setTotal(r.getInteger("total"));
                }
            } else if (source == 1) {
                if (StrUtil.isEmpty(pmut)) {
                    pmut = "0";
                }
                String finalPmut = pmut;

                KnnSearchResponse<PubVectorImageRes> response = null;
                List<Query> list = new ArrayList<>();
                list.add(Query.of(s -> s.term(f -> f.field("pm").value(finalPmut))));
                list.add(Query.of(s -> s.term(f -> f.field("doi.keyword").value(finalPmut))));
                list.add(Query.of(s -> s.term(f -> f.field("ut.keyword").value(finalPmut))));
                Query of = Query.of(q -> q.bool(b -> b.mustNot(list)));

                response = esClient.knnSearch(builder -> builder.index("picture_vector_self")
                        .filter(of)
                        .knn(s -> s.field("vector").queryVector(searchVector).k(topK).numCandidates(topK)), PubVectorImageRes.class);


                TotalHits total = response.hits().total();
                boolean isExactResult = total.relation() == TotalHitsRelation.Eq;
                if (response != null) {
                    return new FetchVectorVoStep().setData(response.hits().hits().stream().map(hit -> {
                        PubVectorImageRes p = hit.source();
                        p.setScore(hit.score().toString());
                        return p;
                    }).collect(Collectors.toList())).setTotal(response.hits().hits().size());
                }
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return null;

    }

    public FetchVectorVoStep pubSearchImage(Integer topK, List<Double> searchVector, List<String> rids, String pmut) {
        try {
            if (StrUtil.isEmpty(pmut)) {
                pmut = "0";
            }
            String finalPmut = pmut;

            KnnSearchResponse<PubVectorImageRes> response = null;
            List<Query> list = new ArrayList<>();
            list.add(Query.of(s -> s.term(f -> f.field("pm").value(finalPmut))));
            list.add(Query.of(s -> s.term(f -> f.field("doi.keyword").value(finalPmut))));
            list.add(Query.of(s -> s.term(f -> f.field("ut.keyword").value(finalPmut))));

            List<FieldValue> values = rids.stream().map(rid -> FieldValue.of(rid)).collect(Collectors.toList());
            Query of = Query.of(q -> q.bool(b -> b.mustNot(list).must(TermsQuery.of(t -> t.field("rid").terms(new TermsQueryField.Builder().value(values).build()))._toQuery())));
            response = esClient.knnSearch(builder -> builder.index("picture_vector_self")
                    .filter(of)
                    .knn(s -> s.field("vector").queryVector(searchVector).k(topK).numCandidates(topK)), PubVectorImageRes.class);


            TotalHits total = response.hits().total();
            boolean isExactResult = total.relation() == TotalHitsRelation.Eq;
            if (response != null) {
                return new FetchVectorVoStep().setData(response.hits().hits().stream().map(hit -> {
                    PubVectorImageRes p = hit.source();
                    p.setScore(hit.score().toString());
                    return p;
                }).collect(Collectors.toList())).setTotal(response.hits().hits().size());
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return null;
    }

    public NcbiPdfToJpg getImgData(Integer aid, String tableMark) {
        FetchVectorVo fetchVectorVo = new FetchVectorVo().setSerial_id(aid).setTableMark(tableMark);
        try {
            String post = HttpUtil.post(centralServer + "centralapi/fetchPic", JSONObject.toJSONString(fetchVectorVo));
            JSONObject r = JSONObject.parseObject(post);
            if (r.getInteger("code").equals(0)) {
                return r.getObject("data", NcbiPdfToJpg.class);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return null;
    }

    public byte[] fetchlinePath(String picKey) {
        FetchVectorVo fetchVectorVo = new FetchVectorVo().setPicKey(picKey);
        try {
            String post = HttpUtil.post(centralServer + "fetchlinePath", JSONObject.toJSONString(fetchVectorVo));
            JSONObject r = JSONObject.parseObject(post);
            if (r.getInteger("code").equals(0)) {
                return r.getObject("data", byte[].class);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return null;
    }

    public TextParagraph getTextDomainById(String aid, String tableMark) {
        FetchVectorVo fetchVectorVo = new FetchVectorVo().setSerial_id(Integer.valueOf(aid)).setTableMark(tableMark);
        try {
            String post = HttpUtil.post(centralServer + "getTextDomainById", JSONObject.toJSONString(fetchVectorVo));
            JSONObject r = JSONObject.parseObject(post);
            if (r.getInteger("code").equals(0)) {
                return r.getObject("data", TextParagraph.class);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return null;

    }

    public String getTxtById(Integer segment, Integer sentence, String tableMark, Integer aid) {
        FetchVectorVo fetchVectorVo = new FetchVectorVo().setSerial_id(Integer.valueOf(aid)).setTableMark(tableMark).setSegment(segment).setSentence(sentence);
        try {
            String post = HttpUtil.post(centralServer + "getTxtById", JSONObject.toJSONString(fetchVectorVo));
            JSONObject r = JSONObject.parseObject(post);
            if (r.getInteger("code").equals(0)) {
                return r.getObject("data", String.class);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return null;
    }

    public String getPreById(Integer segment, Integer sentence, String tableMark, Integer aid) {
        FetchVectorVo fetchVectorVo = new FetchVectorVo().setSerial_id(Integer.valueOf(aid)).setTableMark(tableMark).setSegment(segment).setSentence(sentence);
        try {
            String post = HttpUtil.post(centralServer + "getPreById", JSONObject.toJSONString(fetchVectorVo));
            JSONObject r = JSONObject.parseObject(post);
            if (r.getInteger("code").equals(0)) {
                return r.getObject("data", String.class);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return null;
    }

    @PostMapping("getNextById")
    @ResponseBody
    public String getNextById(Integer segment, Integer sentence, String tableMark, Integer aid) {
        FetchVectorVo fetchVectorVo = new FetchVectorVo().setSerial_id(Integer.valueOf(aid)).setTableMark(tableMark).setSegment(segment).setSentence(sentence);
        try {
            String post = HttpUtil.post(centralServer + "getNextById", JSONObject.toJSONString(fetchVectorVo));
            JSONObject r = JSONObject.parseObject(post);
            if (r.getInteger("code").equals(0)) {
                return r.getObject("data", String.class);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return null;
    }

    public String getPmid(String tableMark, Integer aid) {
        FetchVectorVo fetchVectorVo = new FetchVectorVo().setSerial_id(Integer.valueOf(aid)).setTableMark(tableMark);
        try {
            String post = HttpUtil.post(centralServer + "centralapi/getPmid", JSONObject.toJSONString(fetchVectorVo));
            JSONObject r = JSONObject.parseObject(post);
            if (r.getInteger("code").equals(0)) {
                return r.getObject("data", String.class);
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
        return null;
    }

    public String getUtPmid(String tableMark, Integer aid) {
        FetchVectorVo fetchVectorVo = new FetchVectorVo().setSerial_id(Integer.valueOf(aid)).setTableMark(tableMark);
        try {
            String post = HttpUtil.post(centralServer + "centralapi/getUtPmid", JSONObject.toJSONString(fetchVectorVo));
            JSONObject r = JSONObject.parseObject(post);
            if (r.getInteger("code").equals(0)) {
                return r.getObject("data", String.class);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return null;
    }

    public boolean saveOrUpdateBatch(String tableMark, List<NcbiPdfToJpg> list) {
        FetchVectorVo fetchVectorVo = new FetchVectorVo().setList(list).setTableMark(tableMark);
        try {
            String post = HttpUtil.post(centralServer + "centralapi/saveOrUpdateBatch", JSONObject.toJSONString(fetchVectorVo));
            JSONObject r = JSONObject.parseObject(post);
            if (r.getInteger("code").equals(0)) {
                return r.getObject("data", Boolean.class);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return false;
    }

    public Integer saveOrUpdate(String tableMark, List<NcbiPdfToJpg> list) {
        FetchVectorVo fetchVectorVo = new FetchVectorVo().setList(list).setTableMark(tableMark);
        try {
            String post = HttpUtil.post(centralServer + "centralapi/saveOrUpdate", JSONObject.toJSONString(fetchVectorVo));
            JSONObject r = JSONObject.parseObject(post);
            if (r.getInteger("code").equals(0)) {
                return r.getObject("data", Integer.class);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return 0;
    }
}
